/**
 * @file       png.c
 * @author     ChenBlue
 * @email      chenblue952@163.com
 * @version    V1.0
 * @date       2022-05-15
 * @brief      png decode
 */

#include "./format_change.h"
#include <malloc.h>
#include <png.h>
#include <stdio.h>

void png_decode(const char* file_nmae, unsigned char* buf)
{
	FILE* file = fopen(file_nmae, "rb");
	if (!file) {
		printf("open %s fail\n", file_nmae);
		return;
	}

	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr) {
		png_destroy_read_struct(&png_ptr, &info_ptr, 0);
		return;
	}
	setjmp(png_jmpbuf(png_ptr));

	png_init_io(png_ptr, file);
	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);

	int m_width = png_get_image_width(png_ptr, info_ptr);
	int m_height = png_get_image_height(png_ptr, info_ptr);

	int color_type = png_get_color_type(png_ptr, info_ptr);

	printf("m_width %d m_height %d  color_type %d\n", m_width, m_height, color_type);
	printf("PNG_COLOR_TYPE_RGB_ALPHA %d\n\n", PNG_COLOR_TYPE_RGB_ALPHA);
	int bit_depth = 0;
	int interlace_type = 0;
	unsigned int height;
	unsigned int width;
	png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, 0, 0);
	printf("m_width %d m_height %d  color_type %d  bit_depth %d interlace_type %d \n", m_width, m_height, color_type, bit_depth, interlace_type);

	if (bit_depth == 16)
		png_set_strip_16(png_ptr);
	if (color_type == PNG_COLOR_TYPE_PALETTE)
		png_set_expand(png_ptr);
	if (bit_depth < 8)
		png_set_expand(png_ptr);
	if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
		png_set_expand(png_ptr);
	if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
		png_set_gray_to_rgb(png_ptr);

	int size = m_height * m_width * 4;

	unsigned char* bgra = malloc(size);
	int pos = 0;
	png_bytep* row_pointers = png_get_rows(png_ptr, info_ptr);
	for (int i = 0; i < m_height; i++) {
		for (int j = 0; j < (4 * m_width); j += 4) {
			bgra[pos++] = row_pointers[i][j];     // red
			bgra[pos++] = row_pointers[i][j + 1]; // green
			bgra[pos++] = row_pointers[i][j + 2]; // blue
			//bgra[pos++] = row_pointers[i][j + 3]; // alpha
		}
	}
	png_destroy_read_struct(&png_ptr, &info_ptr, 0);


	rgb888to565(bgra, buf, m_height * m_width);

	fclose(file);
}
